
/*******************************************************************************
 * The code below this comment is integral part of the project "Jelliphy".
 * 
 * "Jelliphy" is a project created by: 
 * Dispage - Patrizio Gelosi
 * Via A. De Gasperi 91 
 * P. Potenza Picena (MC) - Italy
 * 
 * (Hereby referred to as "DISPAGE")
 * 
 * Copyright (c) 2011 DISPAGE.
 * 
 * @Released on: 02-06-2011
 * @Version: 1.0.00
 * @Build: 1109
 * @Site: http://www.dispage.com
 * @Contacts: http://www.dispage.com/contacts
 * 
 * The contents of this file are released under the GNU General Public License
 * version 3 as published by the Free Software Foundation that can be found at
 * the address "http://opensource.org/licenses/gpl-3.0.html". If the license
 * cannot be found, write to the Free Software Foundation, Inc., 51 Franklin
 * Street, Fifth Floor, Boston, MA 02110-1301 USA.
 * 
 * You may not use the present file except in compliance with the License.
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 * 
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU General Public License version 3.
 * 
 * In accordance with Section 7(b) of the GNU General Public License version 3,
 * these Appropriate Legal Notices must retain the display of the "Powered by
 * Dispage" logo. If the display of the logo is not reasonably feasible for
 * technical reasons, the Appropriate Legal Notices must display the words
 * "Powered by Dispage".
 * 
 ******************************************************************************/

var MGED = new function () {

	var that = this,

		colorPaletteDim = {width: 545, height: 298},

		directions = ['top', 'left', 'bottom', 'right'],
		
		typeSpecMap = {
			LI : 'list',
			UL : 'list', 
			OL : 'list',
			TABLE : 'table'
		},
		tablePropMap = {
			columns : 'setTableColumns',
			rows : 'setTableRows',
			withheader : 'toggleTableHeader'
		},
		attrPropMap = {
			attr : 'extAttributes',
			property : 'extProperties'
		},

		bsir = {
			'opera': {m: 6, n: -2},
			'default': {m: 5, n: 5}
		},

		imagePropRx = /(?:^|-)((?:background|list-style)-image|src)$/,
		propDirRx = /-(?:top|right|bottom|left)(?:-?(?:right|left))?/,

		quickPropClicked, maxZIndex, minZIndex, updatingProp,
		updatedDirs = {margin: 0, padding: 0, border: 0},
		
		isCSS,

		savingSpinner = {},

		$shadowPanel, $shadowBase, shadowBasePos, $shadowTarget, shadowWhich, shadowPropName,
		lastTextShadow = {text : '2px 2px 2px', box : '5px 5px 2px'},
		shadowOffset = {},
		shadowMatch = /^\s*(?:(rgba?\([^\)]*\))\s+)?([^\s*]+)(?:\s+([^\s*]+))?(?:\s+([^\s*]+))?(?:\s+([^\s*]+))?/,


		
		displayProperty = function (p, v) {

			return MGUtils.cutText(v, 30, p == 'background-image');
		},

		adaptInput2Opera = function ($el) {

			$el.attr('size', $el.attr('size') +3);
		},

		getPropGroups = function (p) {
			
			if (p.search(propDirRx) != -1) {
				return p.replace(propDirRx, '');
			}
			else {
				return p.replace(/-(?!collapse$|spacing$|radius$).*$/, '');
			}
		},

		getMaxZindex = function () {

			var res = 0;

			JlQ('body > *:not(.mg-nohighlight)').find('*').andSelf().each(function () {
				var $this = JlQ(this), z;
				
				if ($this.css('position') != 'static' && (z = parseInt($this.css('z-index'))) && z > res) {
					res = z;
				}
			});
			return res;
		},

		getMinZindex = function () {

			var res = 0;

			JlQ('body > *:not(.mg-nohighlight)').find('*').andSelf().each(function () {
				var $this = JlQ(this), z;
				
				if ($this.css('position') != 'static' && (z = parseInt($this.css('z-index'))) && z < res) {
					res = z;
				}
			});
			return res;
		},

		addAttributeEntry = function () {

			if (JlQ('.mg-added-attr').length) {
				JlQ('#mg-new-attr-name').focus();
				return;
			}
			if (JlQ('.mg-property-input').length) {
				cancelProperty();
			}
			if (JlQ('#mg-elprop-attr').text() == 'None')	{
				JlQ('#mg-elprop-attr').empty();
			}
			
			var browser = JlQ.uaMatch(navigator.userAgent).browser,
				bRate = typeof (bsir[browser]) == 'undefined' ? bsir['default'] : bsir[browser],
				contW = JlQ(this).closest('.mg-subpanel-group').width(),
				attrSize = Math.floor((contW / bRate.m - bRate.n) / 3 - 3),
				elSize = attrSize * 2;

			JlQ('#mg-elprop-attr').append('<div class="mg-changeable-prop mg-removable-attr mg-added-attr"><input type="text" class="mg-input mg-property-input" id="mg-new-attr-name" size="'+attrSize+'" /><span> : </span><input type="text" class="mg-input mg-property-input" id="mg-new-attr-value" size="'+elSize+'" /></div>');
			JlQ('#mg-new-attr-name').focus();
			JlQ('#mg-new-attr-name, #mg-new-attr-value').keypress(function(event) {
				switch (event.keyCode) {
					case 13:
						saveNewAttr(event);
						break;
					case 27:
						JlQ('.mg-added-attr').remove();
						break;
				}
			});
		},

		addNestedProp = function (p) {

			var ancestor = getPropGroups(p),
				$anc, $parent, spcHtml, iniStat, iniDisp;
			
			if (ancestor == p || !MGDefs.shProps[ancestor]) return '';

			$anc = JlQ('.mg-panel-properties #mg-elproperty-' + ancestor);
			spcHtml = ' mg-prop-indent1';
			if (ancestor == 'background') {
				iniStat = 'collapse';
				iniDisp = '';
			}
			else {
				iniStat = 'expand';
				iniDisp = ' mg-hidden';
			}
			if (!$anc.siblings('.mg-prop-trigger').length) {
				$parent = $anc.parent();
				if ($parent.hasClass('mg-prop-indent1')) {
					spcHtml = ' mg-prop-indent2';
				}
				$parent.prepend('<div class="mg-prop-sub-space mg-prop-trigger mg-prop-'+iniStat+'"></div>');
			}
			else if ($anc.parent('.mg-prop-indent1').length) {
				spcHtml = ' mg-prop-indent2';
			}
			return iniDisp + spcHtml + '" proppar="' + ancestor + '">';
		},

		editColorCommit = function (color, context) {

			var c = color.val('all'),
				v;
			
			JlQ('.mg-panel-jpicker').addClass('mg-hidden');
			if (c == null)	{
				v = 'inherit';
			}
			else if (c.a != 100) {
				v = 'rgb('+c.r+','+c.g+','+c.b+','+c.a+')';
			}
			else {
				v = 'rgb('+c.r+','+c.g+','+c.b+')';
			}
			if (!quickPropClicked && JlQ('.mg-property-input').val().search(/! *important/) != -1) {
				v += ' !important';
			}
			if (typeof(this.id) != 'undefined') {
				if (!quickPropClicked) {
					JlQ('.mg-property-input').val(v);
					saveProperty();
				}
				else if (quickPropClicked == 'shadow-color') {
					if (v == 'inherit') v = '';
					quickCallbacks.backgroundcolor.reverse(v, JlQ('#mg-qp-shadow-color'));
					updateShadow();
				}
				else {
					changeElementProperty(null,  'mg-elproperty-' + quickPropClicked, v);
					updatePropPanel(quickPropClicked, v);
				}
			}
			JlQ.jPicker.List[0].destroy();

			MGTut.nextStep('colorPicker');
		},

		editColorCancel = function (noTut) {

			JlQ('.mg-panel-jpicker').addClass('mg-hidden');
			JlQ.jPicker.List[0].destroy();

			if (typeof(this.id) != 'undefined') {
				cancelProperty();
			}
			if (noTut !== true) MGTut.nextStep('colorPicker');
		},

		getColorProperties = function (color) {

			var rgb = color.match(/^rgba?\((\d+), *(\d+), *(\d+)(?:, *(\d+))? *\)/i),
				res = {};

			if (!rgb) {
				rgb = color.match(/^#([0-9a-f]{2}[0-9a-f]{2}[0-9a-f]{2})/i);
				if (rgb) {
					return {hex: rgb[1]};
				}
				else if (MGDefs.colorHex[color]) {
					rgb = MGDefs.colorHex[color];
				}
			}
			else {
				rgb.splice(0, 1);
			}
			if (!rgb || typeof(rgb[3]) != 'undefined' && rgb[3] == '0') {
				rgb = [255, 255, 255];
			}
			else if (rgb.length > 3 && (typeof(rgb[3]) == 'undefined' || !rgb[3].length)) {
				rgb.splice(3, 1);
			}
			if (typeof(rgb[3]) != 'undefined') {
				that.lastColorHasAlpha = true;
				res.ahex = MGUtils.rgba2ahex(rgb);
			}
			else {
				that.lastColorHasAlpha = false;
				res.hex = MGUtils.rgba2ahex(rgb);
			}	
			return res;
		},

		editColor = function (color) {

			var isShadow = quickPropClicked == 'shadow-color',
				pClass = isCSS ? '.mg-panel-domtree' : (isShadow ? '.mg-panel-shadow' : '.mg-panel-properties'),
				p = MGUtils.getWindowPosition(pClass),
				pw = JlQ(pClass).width(),
				$jip = JlQ('#mg-inline-jpicker'),
				colorDefs = getColorProperties(color || JlQ('.mg-property-input').val());

			$jip.jPicker({
				
					window: {
						alphaSupport: that.lastColorHasAlpha
					},
				
					images : {
						clientPath: MGAddPath + 'custom/mg/js/jpicker/images/'
					},
					color: {
						active: new JlQ.jPicker.Color(colorDefs)
					}
				},
				editColorCommit
			);
			
			if (!isCSS && !isShadow) {
				p.top += 100;
			}
			if (p.left + pw + colorPaletteDim.width +15 > JlQ(window).width())	{
				p.left = p.left -colorPaletteDim.width -15;
			}
			else {
				p.left += pw +10;
			}

			JlQ('.mg-panel-jpicker').css({
					top: p.top,
					left: p.left,
					'z-index': ++MGP.maxZIndex
				}).removeClass('mg-hidden');
			
			setTimeout(function () {
				JlQ('.mg-panel-jpicker .Cancel:first').unbind('click').bind('click', editColorCancel);
				JlQ('.jPicker .Button input').hover(MGBP.hoverButtons)
					.mousedown(function () {JlQ(this).addClass('mg-button-down')})
					.mouseup(function () {JlQ(this).removeClass('mg-button-down')});
			}, 0);
		},

		editShadow = function (which) {

			var isBox = (which == 'box'),
				$blur, $spread, curShadow;
			
			shadowWhich = which;
			shadowPropName = which + '-shadow';
			if (isBox) shadowPropName = MGDefs.cbSelected + shadowPropName; 

			$blur = JlQ('#mg-qp-shadow-blur'),
			$spread = JlQ('#mg-qp-shadow-spread'),
			curShadow = JlQ('#mg-elproperty-' + shadowPropName).attr('mgtitle');

			$shadowPanel.css(MGUtils.getWindowPosition(JlQ('.mg-panel-properties'), {top: 0, left: 15}, '.mg-panel-shadow'))
				.toggleClass('mg-panel-box-shadow', isBox)
				.removeClass('mg-hidden')
				.children('.mg-panel-header').html(MGLang.common[which + '_shadow_title']);

			JlQ('.mg-elprop-box-specific').toggleClass('mg-hidden', !isBox);

			shadowBasePos = $shadowBase.position();

			$shadowBase.html(MGLang.common[which + '_shadow_text']);
			$shadowTarget.html('<div></div>' + MGLang.common[which + '_shadow_text'])
				.draggable({
					containment: "parent",
					drag: showShadowCoor
				});

			if (!$blur.next('.JLui-spinner').length) {
				if (JlQ.browser.opera) adaptInput2Opera($blur);
				$blur.spinner({min: 0, max: 100}).keyup(updateShadow);
				$blur.next().find('span').mouseup(updateShadow);
			}
			if (isBox && !$spread.next('.JLui-spinner').length) {
				if (JlQ.browser.opera) adaptInput2Opera($spread);
				$spread.spinner().keyup(updateShadow);
				$spread.next().find('span').mouseup(updateShadow);
			}
			if (curShadow != 'none') {
				updateShadowPanel(curShadow);
				updateShadowCoor();
			}
			else {
				updateShadowPanel(lastTextShadow[which]);
				updateShadowCoor();
				updateShadow();
			}
			MGP.bringToFront($shadowPanel);
		},

		showShadowCoor = function (ev, ui) {

			updateShadowCoor(ui.position);
			MGP.showTitles.call(this, {type : 'mouseover', clientX: ev.clientX, clientY: ev.clientY});
			updateShadow();
		},

		getShadowString = function (forceColor) {

			var color = JlQ('#mg-qp-shadow-color').attr('mgtitle'),
				blur = JlQ('#mg-qp-shadow-blur').val(),
				spread,
				res = '';

			if (blur == '0' && !shadowOffset.x && !shadowOffset.y) return 'none';

			if (!color && forceColor) color = JlQ('#mg-elproperty-color').attr('mgtitle');
			if (color) res += color + ' ';

			res += shadowOffset.x + 'px ' + shadowOffset.y + 'px ' + blur + 'px';

			if (shadowWhich == 'box') {
				spread = JlQ('#mg-qp-shadow-spread').val();
				if (spread != '0') res += ' ' + spread + 'px';
			}
			return res;
		},

		getIETextShadow = function (value) {

			var m = value.match(shadowMatch);

			if (value == 'none' || !m[2] && !m[3] && !m[4]) return '.textShadowRemove()';

			else return '.textShadow({text: "' + value + '"})';
		},

		updateShadow = function () {

			if (MGP.currentMode == 'Edit' && !JlQ.browser.msie) {
				MGD.$lastCalled.css(shadowPropName, getShadowString(JlQ.browser.webkit));
			}
		},

		updateShadowPanel = function (shadow) {

			var m = shadow.match(shadowMatch);

			if (m[1]) {
				quickCallbacks.backgroundcolor.reverse(m[1], JlQ('#mg-qp-shadow-color'));
			}
			if (m[2] && m[3]) {
				$shadowTarget.css({top: shadowBasePos.top + parseInt(m[3]), left: shadowBasePos.left + parseInt(m[2])});
			}
			if (m[4]) {
				JlQ('#mg-qp-shadow-blur').val(parseInt(m[4]));
			}
			if (m[5]) {
				JlQ('#mg-qp-shadow-spread').val(parseInt(m[5]));
			}
		},

		updateShadowCoor = function (p) {

			if (!p) p = $shadowTarget.position();

			shadowOffset.x = p.left - shadowBasePos.left;
			shadowOffset.y = p.top - shadowBasePos.top;

			$shadowTarget.attr('mgtitle', 'x: ' + shadowOffset.x + '<br>y: ' + shadowOffset.y);
		},

		editElementText = function () {

			if (!MGD.$lastCalled.length || !checkAllowedAction()) return;

			MGTut.nextStep('contentSec');

			that.openEditarea('edit', MGD.$lastCalled.html().replace(/&amp;/g, '&'), {
				syntax_selection_allow: 'css,html,js',
				save_callback: 'MGED.restoreText'
			});
		},

		editFile = function () {
			
			MGF.clickFile.call(JlQ(isCSS ? '#mg-domtree' : '.mg-panel-properties').get(0), 'select');

			if (JlQ.browser.safari) {
				JlQ('#mg-file-upload').css('width', '310px');
			}
		},

		initAutocomplete = function (id) {
			
			var prop, choices, isProp, autoList;

			if (id.match(/^mg-elproperty-/)) {
				prop = id.replace(/^mg-elproperty-/, '').toLowerCase();
				isProp = true;
			}
			else {
				prop = id.replace(/^mg-elattr-/, '').toLowerCase();
				isProp = false;
			}
			autoList = isProp ? 'autoProps' : 'autoAttrs'; 
			if (typeof(MGDefs[autoList][prop]) == 'undefined') {
				choices = [];
			}
			else {
				choices = MGDefs[autoList][prop];
			}
			if (isProp && JlQ.inArray('inherit', choices) == -1) {
				choices.push('inherit'); 
			}
			JlQ('input#'+id).autocomplete({
				minLength: 0,
				select: selectAutocomplete,
				open: openAutocomplete,
				source: choices
			})
				.click(clickAutocomplete);

			JlQ('.JLui-autocomplete').addClass('mg-nohighlight');
		},

		clickAutocomplete = function (ev) {

			JlQ(this).autocomplete('search', '');

			ev.stopPropagation();
		},

		closeAutocomplete = function () {
			
			if (JlQ('.JLui-autocomplete-input').length) {
				JlQ('.JLui-autocomplete-input').autocomplete("close");
			}
		},

		selectAutocomplete = function(event, ui) { 
			
			var v = JlQ(this).val();

			if (v && v.search(/! *important/) != -1 && typeof(ui.item) != 'undefined') {
				ui.item.value += ' !important';
			}
		},

		openAutocomplete = function () {

			JlQ('.JLui-autocomplete').css({
				zIndex: JlQ(this).closest('.mg-panel').css('z-index') * 2,
				width: JlQ(this).width()
			});
			JlQ('.JLui-autocomplete a').attr('href', 'javascript:void(0);');
		},

		quickCallbacks = {

			backgroundcolor : {
				
				straight : function () {

					editColor(JlQ('#mg-qp-background-color').css('background-color'));
					MGTut.nextStep('background');
				},
				
				reverse : function (value, $el) {

					var $picker = $el || JlQ('#mg-qp-background-color');

					if (!value || value == 'transparent' || value == 'inherit' || value == 'rgba(0, 0, 0, 0)') {
						$picker.addClass('mg-empty-background');
					}
					else {
						$picker.css('background-color', value).removeClass('mg-empty-background');
					}
					$picker.attrMgtitle(value);
				},

				defStatus : 'transparent'
			},

			backgroundimage : {
				
				straight : function () {

					editFile();
				},
				
				reverse : function (value) {

					var $picker = JlQ('#mg-qp-background-image');

					if (!value || value == 'none' || value == 'inherit') {
						$picker.addClass('mg-empty-background').removeClass('mg-imaged-background');
						JlQ('#mg-qp-background-image-cover').show();
					}
					else {
						$picker.addClass('mg-imaged-background').removeClass('mg-empty-background');
						JlQ('#mg-qp-background-image-cover').hide();
					}
					$picker.attrMgtitle(value);
				},

				defStatus : 'none'
			},

			backgrounddelete : {
				
				straight : function () {

					changeElementProperty(null, 'mg-elproperty-background-image', 'none');
				}
			},

			backgroundrepeat : {
				
				straight : function () {

					var $this = JlQ(this),
						curRep = $this.css('background-repeat'),
						repPos = JlQ.inArray(curRep, MGDefs.autoProps['background-repeat']),
						newRep = MGDefs.autoProps['background-repeat'][(repPos +1) % 4];

					$this.css('background-repeat', newRep).attrMgtitle(newRep);
					registerProp('background-repeat', newRep);

					return curRep;
				},
				
				reverse : function (value) {

					JlQ('#mg-qp-background-repeat').css('background-repeat', value).attrMgtitle(value);
				},

				defStatus : 'repeat'
			},

			bordercolor : {
				
				straight : function () {

					editColor(JlQ('#mg-qp-border-color').attr('mgtitle'));
				},
				
				reverse : function (value) {

					var $picker = JlQ('#mg-qp-border-color');

					if (value.search(/\s/) == -1) {
						$picker.css('background-color', value).html('');
					}
					else {
						$picker.css('background-color', 'transparent').html('<div class="mg-border-multicol" style="border-color:' + value + ';"></div>');
					}
					$picker.attrMgtitle(value);
				},

				defStatus : 'inherit'
			},

			borderradius : {
				
				straight : function () {

					registerProp(MGDefs.cbSelected + 'border-radius', String(JlQ('#mg-qp-border-radius').val()) + 'px');
				},
				
				reverse : function (value) {

					JlQ('#mg-qp-border-radius').val(!value || value.indexOf(' ') == -1 ? parseInt(value || 0) : '----');
				},

				defStatus : '0px'
			},

			borderstyle : {
				
				straight : function ($clicked) {
					
					var value = $clicked.attr('mgtitle');

					if (!value || $clicked.is('#mg-border-style-current') || $clicked.parent('#mg-border-style-current').length) return;

					JlQ('#mg-border-style-current > div').replaceWith($clicked.clone());

					registerProp('border-style', value);

					JlQ.each(MGDefs.shProps['border-width'], function () {
						updateQuickProps(this, JlQ('#mg-elproperty-' + this).attr('mgtitle'), true);
					});
				},

				reverse : function (value) {
	
					var css, html = '';
					
					if (value.search(/none|hidden/) != -1) {
						css = {
							borderStyle: value.replace(/none|hidden/g, 'solid'),
							borderColor: value.replace(/none|hidden/g, '#F0E9E8').replace(/(^|\s)\w+/gi, '$1#000000')
						};
						if (value.indexOf(' ') == -1) {
							html = '<div class="mg-choice-label">' + value + '</div>';
						}
					}
					else {
						css = {
							borderStyle: value,
							borderColor: '#000000'
						};
					}
					JlQ('#mg-border-style-current > div').css(css).attr('mgtitle', value).html(html);
				},

				defStatus : 'none'
			},

			boxshadow : {
				
				straight : function () {
					
					var $parent = JlQ(this).parent(),
						res = $parent.hasClass('mg-button-down') ? 'none' : lastTextShadow.box;

					$parent.toggleClass('mg-button-down').attrMgtitle(res);
					registerProp(MGDefs.cbSelected + 'box-shadow', res);
				},

				reverse : function (value) {
	
					if (!value) value = 'none';

					JlQ('#mg-qp-box-shadow').parent().attrMgtitle(value).toggleClass('mg-button-down', value != 'none');
				},

				defStatus : 'none'
			},

			boxshadowmore : {
				
				straight : function () {

					if ($shadowPanel.hasClass('mg-hidden')) {
						editShadow('box');
					}
					else {
						cancelShadow();
					}
				}
			},

			color : {
				
				straight : function () {

					editColor(JlQ('#mg-qp-color').css('background-color'));
				},
				
				reverse : function (value) {

					JlQ('#mg-qp-color').css('background-color', value).attrMgtitle(value);
				},

				defStatus : 'inherit'
			},

			display : {
				
				straight : function () {
					
					var $this = JlQ(this),
						oldValue = $this.attr('mgtitle');

					if ($this.hasClass('mg-ico-display-1')) {
						$this.removeClass('mg-ico-display-1').addClass('mg-ico-display-2');
						registerProp('visibility', 'hidden');
						res = 'hidden';
					}
					else if ($this.hasClass('mg-ico-display-2')) {
						$this.removeClass('mg-ico-display-2').addClass('mg-ico-display-3');
						registerProp('visibility', 'visible');
						registerProp('display', 'none');
						res = 'none';
					}
					else if ($this.hasClass('mg-ico-display-3')) {
						$this.removeClass('mg-ico-display-3').addClass('mg-ico-display-1');
						registerProp('display', MGD.$lastCalled.data('qval-display') || 'block');
						res = 'default';
					}
					$this.attrMgtitle(res);

					return oldValue;
				},
				
				reverse : function (value) {

					var $icon = JlQ('#mg-qp-display'),
						res;

					if (value == 'none') {
						$icon.removeClass('mg-ico-display-1 mg-ico-display-2').addClass('mg-ico-display-3');
						res = 'none';
					}
					else if (MGD.$lastCalled && MGD.$lastCalled.css('visibility') == 'hidden' && value != 'default') {
						$icon.removeClass('mg-ico-display-1 mg-ico-display-3').addClass('mg-ico-display-2');
						res = 'hidden';
					}
					else {
						$icon.removeClass('mg-ico-display-2 mg-ico-display-3').addClass('mg-ico-display-1');
						res = 'default';
					}
					$icon.attrMgtitle(res);
				},

				defStatus : 'default'

			},

			fontfamily : {
				
				straight : function () {

					var v = JlQ(this).val();

					if (JlQ.browser.mozilla) JlQ('#mg-qp-font-family').css('font-family', v);
					registerProp('font-family', v);
				},
				
				reverse : function (value) {
	
					var min = 999999,
						cv;

					value = value.replace(/\'/g, '');

					JlQ('#mg-qp-font-family > option').each(function () {
						var v = JlQ(this).text(),
							i = value.indexOf(v);
						if (i >= 0 && i < min) {
							min = i;
							cv = v;
						}
					});					
					if (cv) {
						if (JlQ.browser.mozilla) JlQ('#mg-qp-font-family').css('font-family', cv);
						JlQ('#mg-qp-font-family').val(cv.replace(/\'/g, ''));
					}
				},

				defStatus : 'Arial'
			},

			fontsize : {
				
				straight : function () {

					registerProp('font-size', JlQ(this).val());
				},
				
				reverse : function (value) {
	
					var $selector = JlQ('#mg-qp-font-size'),
						m, t, hasFound;
					
					if ($selector.children('*:econtains(' + value + ')').length) { 
						$selector.val(value);
					}
					else if (m = value.match(/^(\d+)px$/)) {
						t = parseInt(m[1]);
						$selector.children().each(function () {
							var $this = JlQ(this),
								v = parseInt($this.text());
							if (v > t) {
								$this.before('<option>' + value + '</option>');
								hasFound = true;
								return false;
							}
						});
						if (!hasFound) {
							$selector.append('<option>' + value + '</option>');
						}
						$selector.val(value);
					}

				},

				defStatus : '12px'
			},

			fontplus : {
				
				straight : function () {
					
					var $fontSel = JlQ('#mg-qp-font-size'),
						newFont = $fontSel.children(':selected').next().text();

					if (newFont) {
						JlQ('#mg-qp-font-size').val(newFont);
						registerProp('font-size', newFont);
					}
				}
			},

			fontminus : {
				
				straight : function () {
					
					var $fontSel = JlQ('#mg-qp-font-size'),
						newFont = $fontSel.children(':selected').prev().text();

					if (newFont) {
						JlQ('#mg-qp-font-size').val(newFont);
						registerProp('font-size', newFont);
					}
				}	
			},

			fontweight : {
				
				straight : function () {
					
					var $parent = JlQ(this).parent(),
						res = $parent.hasClass('mg-button-down') ? 'normal' : 'bold';

					$parent.toggleClass('mg-button-down').attrMgtitle(res);
					registerProp('font-weight', res);
				},

				reverse : function (value) {
	
					JlQ('#mg-qp-font-weight').parent().attrMgtitle(value).toggleClass('mg-button-down', value == 'bold' || parseInt(value) > 400);
				},

				defStatus : 'normal'
			},

			fontstyle : {
				
				straight : function () {
					
					var $parent = JlQ(this).parent(),
						res = $parent.hasClass('mg-button-down') ? 'normal' : 'italic';

					$parent.toggleClass('mg-button-down').attrMgtitle(res);
					registerProp('font-style', res);
				},

				reverse : function (value) {
	
					JlQ('#mg-qp-font-style').parent().attrMgtitle(value).toggleClass('mg-button-down', value == 'italic' || value == 'oblique');
				},

				defStatus : 'normal'
			},

			height : {
				
				reverse : function (value) {

					if (value.search(/^[0-9\.]+(?:px)?$/) != -1 && MGD.$lastCalled) value = MGD.$lastCalled.height();
					else value = 0;

					JlQ('#mg-qp-height').text(parseInt(value));
				},

				defStatus : 0
			},

			lineheight : {
				
				straight : function () {

					registerProp('line-height', String(JlQ('#mg-qp-line-height').val()) + JlQ('#mg-qp-lh-um').text());
				},
				
				reverse : function (value) {

					var m = value.match(/^(\d+)(\D*)$/);

					if (m) {
						value = m[1];
						JlQ('#mg-qp-lh-um').text(m[2]);
					}
					else {
						value = "0";
					}
					JlQ('#mg-qp-line-height').val(value);
				},

				defStatus : '1em'
			},

			opacity : {
				
				straight : function () {

					if (MGD.$lastCalled) {
						MGD.$lastCalled.css('opacity', JlQ('#mg-elproperty-opacity').text());
					}
					registerProp('opacity', String(JlQ(this).slider('value')));
				},
				
				reverse : function (value) {

					JlQ('#mg-qp-opacity').slider('value', value);
					JlQ('#mg-qp-opacity > a').attrMgtitle(value);
				},

				defStatus : '1.0'
			},

			position : {
				
				straight : function () {

					return toggleAddQuickPosition.call(this);
				},
				
				reverse : function (value) {

					that.syncPositionProp('#mg-qp-position', value);
					JlQ('#mg-qp-position').attrMgtitle(value);
				},

				defStatus : 'static'
			},

			shadowcolor : {
				
				straight : function () {

					editColor(JlQ(this).css('background-color'));
				}
			},

			textalign : {
				
				straight : function ($clicked) {
					
					var getVal = function ($el) {
							var res = '';
							if ($el.length) {
								res = $el.children().attr('id').replace(/^mg-qp-text-align-/, '');
								if (!res) res = 'left';
							}
							return res;
						},
						$parent = $clicked.closest('.mg-button'),
						newVal = getVal($parent),
						$oldButton = JlQ('#mg-qp-text-align > .mg-button.mg-button-down'),
						oldVal = getVal($oldButton)

					if (oldVal == newVal) {
						newVal = 'left';
						$oldButton = JlQ('#mg-qp-text-align-left').parent();
					}
					$parent.add($oldButton).toggleClass('mg-button-down');

					registerProp('text-align', newVal);

					return oldVal;
				},

				reverse : function (value) {
	
					var $button;
					
					JlQ('#mg-qp-text-align > .mg-button').removeClass('mg-button-down');

					value = value.replace(/^-(moz|o|webkit)-/, '');

					if (value == 'start' || !value) value = 'left';

					$button = JlQ('#mg-qp-text-align-' + value);
					if ($button.length) $button.parent().addClass('mg-button-down');
				},

				defStatus : 'inherit'
			},

			textdecoration : {
				
				straight : function () {
					
					var $parent = JlQ(this).parent(),
						isDown = $parent.hasClass('mg-button-down'),
						res = isDown ? (MGD.$lastCalled.data('qval-textdecoration') || 'none') : 'underline';

					$parent.toggleClass('mg-button-down').attrMgtitle(res);

					registerProp('text-decoration', res);

					return isDown ? '' : 'none';
				},

				reverse : function (value) {
	
					JlQ('#mg-qp-text-decoration').parent().attrMgtitle(value).toggleClass('mg-button-down', value == 'underline');
				},

				defStatus : 'none'
			},

			textindentdecrease : {
				
				straight : function () {
					
					var value = (parseInt(JlQ('#mg-elproperty-text-indent').text()) -4) + 'px';

					registerProp('text-indent', value);
				}
			},

			textindentincrease : {
				
				straight : function () {
					
					var value = (parseInt(JlQ('#mg-elproperty-text-indent').text()) +4) + 'px';

					registerProp('text-indent', value);
				}
			},

			textshadow : {
				
				straight : function () {
					
					var $parent = JlQ(this).parent(),
						res = $parent.hasClass('mg-button-down') ? 'none' : lastTextShadow.text;

					$parent.toggleClass('mg-button-down').attrMgtitle(res);
					registerProp('text-shadow', res);
				},

				reverse : function (value) {
	
					JlQ('#mg-qp-text-shadow').parent().attrMgtitle(value).toggleClass('mg-button-down', typeof(value) != 'undefined' && value != 'none');
				},

				defStatus : 'none'
			},

			textshadowmore : {
				
				straight : function () {

					if ($shadowPanel.hasClass('mg-hidden')) {
						editShadow('text');
						MGTut.nextStep('addTextShadow');
					}
					else {
						cancelShadow();
					}
				}
			},

			texttransform : {
				
				straight : function () {
					
					var $l1 = JlQ('#mg-qp-text-transform'),
						$l2 = JlQ('#mg-qp-text-transform2'),
						res;

					if ($l1.hasClass('mg-ico-tt-au')) {
						if ($l2.hasClass('mg-ico-tt-au')) {
							res = 'lowercase';
						}
						else {
							res = 'none';
						}
						$l1.toggleClass('mg-ico-tt-au');
						$l2.toggleClass('mg-ico-tt-au');
					}
					else {
						if ($l2.hasClass('mg-ico-tt-au')) {
							res = 'uppercase';
						}
						else {
							res = 'capitalize';
						}
						$l1.toggleClass('mg-ico-tt-au');
					}
					registerProp('text-transform', res);
					JlQ('#mg-quick-tt').attrMgtitle(res);
				},

				reverse : function (value) {
	
					switch (value) {
						case 'none':
							JlQ('#mg-qp-text-transform').removeClass('mg-ico-tt-au');
							JlQ('#mg-qp-text-transform2').addClass('mg-ico-tt-au');
							break;
						case 'uppercase':
							JlQ('#mg-qp-text-transform').addClass('mg-ico-tt-au');
							JlQ('#mg-qp-text-transform2').addClass('mg-ico-tt-au');
							break;
						case 'lowercase':
							JlQ('#mg-qp-text-transform').removeClass('mg-ico-tt-au');
							JlQ('#mg-qp-text-transform2').removeClass('mg-ico-tt-au');
							break;
						case 'capitalize':
							JlQ('#mg-qp-text-transform').addClass('mg-ico-tt-au');
							JlQ('#mg-qp-text-transform2').removeClass('mg-ico-tt-au');
							break;
					}
					JlQ('#mg-quick-tt').attrMgtitle(value);
				},

				defStatus : 'none'
			},

			width : {
				
				reverse : function (value) {

					if (value.search(/^[0-9\.]+(?:px)?$/) != -1 && MGD.$lastCalled) value = MGD.$lastCalled.width();
					else value = 0;

					JlQ('#mg-qp-width').text(parseInt(value));
				},

				defStatus : 0
			},

			zindex : {
				
				straight : function () {

					registerProp('z-index', String(JlQ('#mg-qp-z-index').val()));
				},
				
				reverse : function (value) {

					JlQ('#mg-qp-z-index').val(value);
				},

				defStatus : 'auto'
			},

			zindexfront : {
				
				straight : function () {
					
					if (typeof (maxZIndex) == 'undefined') {
						maxZIndex = getMaxZindex();
					}
					maxZIndex++;
					MGD.addTransform("parentsUntil('body').andSelf().css('z-index', '" + maxZIndex + "')", 'bring-top');
					updatePropPanel('z-index', maxZIndex);
					quickCallbacks.zindex.reverse(maxZIndex);
				}
			},

			zindexback : {
				
				straight : function () {
					
					if (typeof (minZIndex) == 'undefined') {
						minZIndex = getMinZindex();
					}
					minZIndex--;
					MGD.addTransform("parentsUntil('body').andSelf().css('z-index', '" + minZIndex + "')", 'bring-top');
					updatePropPanel('z-index', minZIndex);
					quickCallbacks.zindex.reverse(minZIndex);
				}
			}
		},

		eventQuickProp = function (ev) {

			var $this = JlQ(this),
				tmoDriven = (typeof(ev) == 'string'),
				t = tmoDriven && savingSpinner[ev] ? savingSpinner[ev].tg : ($this.is('.mg-quick-icons-container, .mg-qp-border-choices') ? ($this.children('.mg-quick-prop').get(0) || $this.parent('.mg-quick-icons-group').get(0)) : this),
				prop, oldVal, oldStatus;

			if (!t) return;

			quickPropClicked = JlQ(t).attr('id').replace(/^mg-qp-/, '');

			if (tmoDriven) {
				delete savingSpinner[ev];
			}
			else if (typeof(ev) == 'object' && ev.handler) {
				ev.stopPropagation();
			}
			if (quickPropClicked == 'z-index' && document.activeElement != t) return;
			else if (JlQ.browser.msie && quickPropClicked == 'text-shadow') {
				oldVal = MGD.$lastCalled.attr('mgtextshadow');
			}
			else {
				oldVal = MGD.$lastCalled.css(quickPropClicked);
			}
			prop = quickPropClicked.replace(/-/g, '');
			if (typeof(quickCallbacks[prop]) != 'undefined' && quickCallbacks[prop].straight) {
				oldStatus = quickCallbacks[prop].straight.call(t, $this);
				if (oldStatus === quickCallbacks[prop].defStatus) {
					MGD.$lastCalled.data('qval-' + prop, oldVal);
				}
				JlQ('#mg-baloon').remove();
			}
		},

		updateQuickProps = function (prop, value, noConstrain) {

			if (prop) {
				updatingProp = !noConstrain;
				var p = prop.replace(/-/g, ''),
					pTmp;
				
				if ((pTmp = prop.replace(/^(?:-moz-|-webkit-)?(border-).*(?:(color|style)|(radius)(?:-[^\-]+)?)$/, '$1$2$3')) != prop) {
					prop = pTmp;
					p = prop.replace(/-/g, '');
					value = undefined;
				}
				if (quickCallbacks[p]) {
					if (typeof(value) == 'undefined') {
						value = JlQ('#mg-elproperty-' + prop).attr('mgtitle');
					}
					quickCallbacks[p].reverse(value);
				}
				else if (MGDefs.shProps[prop]) {
					JlQ.each(MGDefs.shProps[prop], function () {updateQuickProps(this)});
				}
			}
			else {
				updatingProp = false;
				updatedDirs = {margin: 0, padding: 0, border: 0};

				JlQ('.mg-quick-prop').each(function () {

					var prop = JlQ(this).attr('id').replace(/^mg-qp-/, ''),
						p = prop.replace(/-/g, '');
					
					if (quickCallbacks[p] && quickCallbacks[p].reverse) {
						quickCallbacks[p].reverse(JlQ('#mg-elproperty-' + prop).attr('mgtitle') || JlQ('#mg-elproperty-' + MGDefs.cbSelected + prop).attr('mgtitle'));
					}
				});
			}
		},

		defaultQuickProps = function () {

			JlQ('.mg-quick-prop').each(function () {

				var prop = JlQ(this).attr('id').replace(/^mg-qp-/, '').replace(/-/g, '');
				
				if (quickCallbacks[prop] && quickCallbacks[prop].defStatus) {
					quickCallbacks[prop].reverse(quickCallbacks[prop].defStatus);
				}
			});
		},

		showOpacity = function (ev, ui) {

			var $baloon = JlQ('#mg-baloon'),
				$handle = JlQ('#mg-qp-opacity > a'),
				value = ui.value,
				pos = {};

			$handle.removeAttr('mgtitle');

			if (ev.originalEvent && ev.originalEvent.type == 'keydown') {
				pos = MGUtils.getWindowPosition($handle, {top: 20});
			}
			else {
				pos.left = ev.clientX + MGP.balOff.left;
				pos.top = ev.clientY + MGP.balOff.top;
			}

			if (MGP.currentMode == 'Edit') {
				MGD.$lastCalled.css('opacity', value);
			}
			if ($baloon.length) {
				$baloon.html(value);
			}
			else {
				JlQ('<div id="mg-baloon" class="mg-baloon mg-nohighlight">' + value + '</div>').appendTo('body');
			}
			JlQ('#mg-baloon').css(pos);
		},

		hideOpacity = function (ev, ui) {

			JlQ('#mg-baloon').remove();
			JlQ('#mg-qp-opacity > a').attrMgtitle(ui.value);
		},

		updateSpinnerSize = function (el) {

			if (el.size == 1) {
				JlQ(el).css('font-size', el.value.length > 2 ? '8px' : '11px');
			}
		},

		trySaveSpinner = function (ev) {

			//ev.stopImmediatePropagation();

			var el = this.tagName == 'INPUT' ? this : JlQ(this).closest('.JLui-spinner').prev().get(0),
				id = el.id;

			if (savingSpinner[id]) clearTimeout(savingSpinner[id].tmid);
			
			updateSpinnerSize(el);

			savingSpinner[id] = {
				tg: el,
				tmid: setTimeout('MGED.eventQuickProp("' + id + '")', 1000)
			};
		},

		cancelShadow = function () {

			var v;
			
			if (MGD.$lastCalled) {
				v = JlQ('#mg-elproperty-' + shadowPropName).attr('mgtitle');
				if (JlQ.browser.webkit && v != 'none' && v.search(/rgba?\(/) == -1) v = JlQ('#mg-elproperty-color').attr('mgtitle') + ' ' + v;
				MGD.$lastCalled.css(shadowPropName, v);
			}
			JlQ('.mg-panel-shadow, .mg-panel-jpicker').addClass('mg-hidden');
			
			MGTut.nextStep('textShadowPanel');
		},

		saveShadow = function () {

			var shadow;
			
			cancelShadow();
			shadow = getShadowString();
			if (shadow != 'none') {
				lastTextShadow[shadowWhich] = shadow;
			}
			JlQ('#mg-qp-' + shadowWhich + '-shadow').parent().toggleClass('mg-button-down', shadow != 'none');
			registerProp(shadowPropName, shadow);

			$shadowPanel.addClass('mg-hidden');
		},

		updateBoxConstrain = function (prop) {

			var sel = '#mg-qp-' + prop + '-' + '2replace',
				value, res = true;

			if (prop == 'border') sel += '-width';
			
			JlQ.each(directions, function () {
				var v = JlQ(sel.replace('2replace' ,this)).val();
				
				if (typeof(value) == 'undefined') {
					value = v;
				}
				else if (value != v) {
					res = false;
					return false;
				}
			});
			JlQ('#mg-qp-constrain-' + prop).attr('checked', res);
		},

		quickPanelInit = function () {

			JlQ('.mg-switch-props').click(togglePropView);
			JlQ('span.mg-quick-prop, .mg-quick-icons-container').click(eventQuickProp);
			JlQ('select.mg-quick-prop').change(eventQuickProp);

			JlQ('#mg-qp-opacity').slider({
					max: 1,
					step: 0.1,
					value: 1,
					start: showOpacity,
					slide: showOpacity,
					stop: hideOpacity
				})
				.keyup(eventQuickProp);

			JlQ('#mg-qp-font-family').html(JlQ.map(MGDefs.autoProps['font-family'], function (v) {return '<option '+(JlQ.browser.mozilla ? 'style="font-family:'+v+';"' : '') + '>'+v+'</option>'}).join());

			JlQ('#mg-qp-font-size').html(JlQ.map(MGDefs.autoProps['font-size'], function (v) {return '<option>'+v+'</option>'}).join()).val('12px');

			JlQ('#mg-shadow-cancel, .mg-panel-shadow .JLui-icon-closethick').click(cancelShadow);
			JlQ('#mg-shadow-ok').click(saveShadow);
		},

		updateStyleAttr = function () {
			
			if (!MGD.$lastCalled) return;

			var style = MGD.$lastCalled.attr('style');

			if (JlQ('#mg-elattr-style').length) {
				JlQ('#mg-elattr-style').text(MGUtils.cutText(style, 30)).attr('mgtitle', style);
			}
			else {
				JlQ('#mg-elprop-attr').append('<div class="mg-changeable-prop mg-removable-attr"><span><b>style</b> : </span><span class="mg-changeable-input" id="mg-elattr-style" mgtitle="' + style + '">'+MGUtils.cutText(style, 30)+'</span></div>');
			}
			that.extAttributes.style = style;
		},

		addEditIcons = function (el, cbs) {
			
			var $el = JlQ(el),
				id = $el.children('input:not(#mg-add-rule-name)').attr('id'),
				isProp = id.match(/^mg-elproperty-/),
				pos = isProp ? 5 : 15,
				imp;
			
			JlQ('.JLui-icon-bckg').remove();

			$el.append('<div id="mg-submit-prop" style="right:'+(pos +13)+'px;" class="mg-images mg-images-dark mg-images-overlay JLui-icon-bckg JLui-icon-check-bckg"></div><div id="mg-cancel-prop" style="right:'+pos+'px;" class="mg-images mg-images-dark mg-images-overlay JLui-icon-bckg JLui-icon-close-bckg"></div>');

			if (isProp) {
				imp = ($el.find('input').val().search(/! *important/) != -1) ? 'JLui-icon-info-bckg' : 'JLui-icon-notice-bckg';
				$el.append('<div id="mg-important-prop" style="right:'+(pos + 25)+'px;" class="mg-images mg-images-dark mg-images-overlay JLui-icon-bckg '+imp+'"></div>');

				JlQ('#mg-important-prop').click(addImportant);
			}
			if (id.match(imagePropRx)) {
				$el.append('<div id="mg-open-upload" style="right:'+(pos + (isProp ? 40 : 26))+'px;" class="mg-images mg-images-dark mg-images-overlay JLui-icon-bckg JLui-icon-folder-open"></div>');
				JlQ('#mg-open-upload').click(editFile);
			}
			if (cbs) {
				saveCb = cbs.save;
				cancelCb = cbs.cancel;
			}
			else if ($el.find('#mg-new-attr-name').length) {
				saveCb = saveNewAttr;
				cancelCb = removeAttribute;
			}
			else {
				saveCb = saveProperty;
				cancelCb = cancelProperty;
			}
			JlQ('#mg-submit-prop').click(saveCb);
			JlQ('#mg-cancel-prop').click(cancelCb);
		},

		addImportant = function () {

			var $this = JlQ(this),
				$el = $this.siblings('input:not(#mg-add-rule-name)'),
				v = $el.val();

			if ($this.hasClass('JLui-icon-notice-bckg') && !v.match(/!\s*important/i)) {
				$el.val(v + ' !important');
			}
			else if ($this.hasClass('JLui-icon-info-bckg') && v.match(/!\s*important/i)) {
				$el.val(v.replace(/ *! *important/i, ''));
			}
			$this.toggleClass('JLui-icon-info-bckg JLui-icon-notice-bckg');
		},

		fixProps = function (specProps) {

			JlQ('.mg-panel-properties .mg-changeable-input').each(function () {
				var $this = JlQ(this),
					m = $this.attr('id').match(/^mg-el(attr|property)-(.*)$/),
					prop = m[2],
					value = that[attrPropMap[m[1]]][prop];

				if (!value) return true;

				if (specProps && JlQ.inArray(prop, specProps) != -1) {
					$this.text(displayProperty(prop, value));
				}
				$this.attrMgtitle(value).parent().data('rval', value);
			});
			if (MGD.$lastCalled) {
				if (JlQ.browser.msie) {
					var s = MGD.$lastCalled.attr('mgtextshadow');
					if (!s) s = 'none';
					JlQ('#mg-elproperty-text-shadow').text(s).attrMgtitle(s).parent().data('rval', s);
				}
				else if (JlQ.browser.mozilla) {

				}
			}
		},

		popGroup = function (group, properties) {

			JlQ.each(properties, function (i, p) {
				
				var appTo = '';
				
				if (p.indexOf('-') == -1 || !(appTo = addNestedProp(p))) {
					appTo = '">';
				}
				JlQ('#mg-elprop-' + group).append('<div class="mg-changeable-prop' + appTo + '<span><b>' + p + '</b> : </span><span class="mg-changeable-input" id="mg-elproperty-'+p+'"></span></div>');
			});
		},

		propString = function (prop, val) {
			
			if (MGDefs.cbProps[prop]) {
				var s = MGDefs.cbPropsArr.indexOf(prop);

				s = s - s % 3;
				
				return '{' + JlQ.map(MGDefs.cbPropsArr.slice(s, s +3), function (s) {return '"' + s + '": "' + val + '"'}).join(', ') + '}';
			}
			else return "'" + prop + "', '" + val + "'";
		},

		changeElementProperty = function ($el, id, value, noQuickUpdate) {

			var cap = id.match(/^mg-(elproperty|elattr)-(.*)$/),
				isTableSpec = false,
				code, $parent, ancestor, hadImp, elId;

			if (cap[1] == 'elproperty') {
				if (MGP.currentMode == 'Add' && cap[2] == 'display') {
					elId = MGP.currentAddB.attr('id');
					MGD.updateDefTransform(elId, value);
					MGD.defDisplay[elId] = value;
					MGD.defDispChanged[elId] = true;
					return;
				}
				MGD.currentActionType = 'change-prop';
				if (isCSS && $el && JlQ('#mg-csscanv-panel:visible').length) {
					MGCR.operRule.call($el.get(0), 'editCSS');
				}
				else {
					$parent = JlQ('#' + id).parent();

					if (cap[2].search(imagePropRx) != -1) {
						value = value.replace(/url\s*\((?!\s*http)\s*[\'\"]*/, '$&\' + MGAddPath + \'');
					}
					else if (cap[2].search(/-shadow$/) != -1 && value != 'none' && value.search(/rgba?\(/) == -1) {
						value = JlQ('#mg-elproperty-color').attr('mgtitle') + ' ' + value;
					}
					if ($parent.length) {
						ancestor = $parent.attr('proppar');
					}
					if (value.match(/!\s*important/i)) {
						value = value.replace(/\s*!\s*important\s*/i, '');
						code = "cssImportant(" + propString(cap[2], value) + ")";
					}
					else {
						if ((hadImp = (MGD.hasImportant(MGD.$lastCalled) && MGD.$lastCalled.cssImportant(cap[2]))) || MGDefs.shProps[cap[2]]) {
							if (!hadImp && $parent.data('rval') === value) return;
							code = "cssImportant(" + propString(cap[2], value) + ", true)";
						}
						else {
							if ($parent.data('rval') === value) return;
							code = "css(" + propString(cap[2], value) + ")";
						}
					}
					if (cap[2] == 'text-shadow') {
						code += getIETextShadow(value);
					}
					MGD.addTransform(code);

					if (MGDefs.shProps[cap[2]] || ancestor) {
						MGP.characterizeElement(MGD.$lastCalled, true);
					}
					if (!noQuickUpdate) {
						updateQuickProps(cap[2], value);
					}
					updateStyleAttr();

					if (cap[2] == 'position') {
						if (MGP.currentMode == 'Add') {
							MGMV.initDragDrop(MGP.currentAddB);
						}
						else if (JlQ('#mg-cursor').hasClass('mg-cursor-selected')) {
							MGMV.enrichCursor();
						}
					}
				}
			}
			else {
				if (!MGD.currentActionType) {
					MGD.currentActionType = 'change-attr';
				}

				code = "get(0).setAttribute('"+cap[2]+"', '"+value+"')";

				if (MGD.lastCalled.tagName.toLowerCase() == 'table' && JlQ.inArray(cap[2], ['columns', 'rows', 'withheader']) != -1) {
					code = tablePropMap[cap[2]] + '(' + value + ')' + '.' + code;
					isTableSpec = true;
				}
				MGD.addTransform(code);

				if (isTableSpec) {
					MGMV.makeDroppable(MGD.$lastCalled, true);
				}
			}
		},

		restoreProperty = function ($el, id, val) {

			var $newEl, txt;

			if (isCSS) {
				txt = $el.siblings('input#mg-add-rule-name').length ? $el.siblings('input#mg-add-rule-name').val() : $el.siblings('span').text();
				$newEl = $el.parent().html(txt + ': ' + '<font>' + val + ';</font>');
			}
			else {
				$newEl = $el.replaceWith('<span class="mg-changeable-input" id="'+id+'" mgtitle="' + val + '">' + displayProperty(id.replace(/^mg-elproperty-/, ''), val) + '</span>');
			}
			return $newEl;
		},

		saveProperty = function (ev) {

			if (ev) ev.stopPropagation();

			var $el = JlQ('.mg-property-input'),
				value = $el.val(),
				id = $el.attr('id'),
				$newEl;

			$newEl = restoreProperty($el, id, $el.val());

			changeElementProperty($newEl, id, value);
			JlQ('#'+id).parent().data('rval', value);
			closeProperty(ev);
		},

		saveNewAttr = function (ev) {

			ev.stopPropagation();

			var $attrName = JlQ('#mg-new-attr-name'),
				$attrValue = JlQ('#mg-new-attr-value'),
				attrName = $attrName.val();

			if (!attrName.length) return;

			MGD.currentActionType = 'add-attr';
			$attrName.siblings('span').remove();
			//MGD.addTransform("attr('"+attrName+"', '"+$attrValue.val()+"')");
			$attrName.replaceWith('<span><b>'+attrName+'</b> : </span>');
			$attrValue.attr('id', 'mg-elattr-'+attrName);
			$attrValue.parent().removeClass('mg-added-attr');

			saveProperty();
		},

		registerProp = function (prop, value) {

			changeElementProperty(null, 'mg-elproperty-' + prop, value, true);
			updatePropPanel(prop, value);
		},

		updatePropPanel = function (prop, value) {

			JlQ('.mg-panel-properties #mg-elproperty-' + prop).attrMgtitle(value).text(value).parent().data('rval', value);
		},

		toggleGroupProperties = function () {
			
			var $this = JlQ(this),
				$tgt = $this.parent().next();
			
			MGP.updatePropShown($tgt);
			$tgt.slideToggle(that.activateSpinner);
			$this.toggleClass('JLui-icon-circle-triangle-s').toggleClass('JLui-icon-circle-triangle-n');
			$this.next().toggle();
		},

		togglePropView = function (force) {

			var $this = JlQ(this),
				$tgt = $this.html(MGLang.common.panel_views.replace($this.html(), ''))
					.parent().next(),
				$children = $tgt.children();
			
			MGP.updatePropShown($tgt, force);

			if (typeof(force) == 'string') {
				if (force == 'advanced') {
					$children.first().hide();
					$children.last().show();
				}
				else {
					$children.first().show();
					$children.last().hide();
				}
			}
			else {
				$children.slideToggle(that.activateSpinner);
			}
		},

		toggleAddQuickPosition = function (ev) {

			var $this = JlQ(this),
				position;

			$this.toggleClass('mg-quick-absolute');
			position = $this.hasClass('mg-quick-absolute') ? 'absolute' : 'static';

			if (position == 'static' && MGD.$lastCalled.data('qval-position')) {
				position = MGD.$lastCalled.data('qval-position');
			}
			registerProp('position', position);

			$this.attrMgtitle(position);

			if (ev) ev.stopPropagation();
			else return (position == 'absolute') ? 'static' : 'absolute';
		},

		cancelProperty = function (ev) {

			var $el = JlQ('.mg-property-input'),
				oldVal, id;

			if (!$el.length) return;

			oldVal = $el.parent().data('rval'),
			id = $el.attr('id');

			restoreProperty($el, id, oldVal);

			closeProperty(ev);
		},

		closeProperty = function (ev) {

			if (!JlQ('.mg-panel-jpicker').hasClass('mg-hidden')) {
				editColorCancel();
			}
			JlQ('.mg-panel-filemanage, .mg-panel-shadow').addClass('mg-hidden');
			JlQ('.JLui-icon-bckg').remove();

			if (typeof(ev) != 'undefined') ev.stopPropagation();
		},

		checkAllowedAction = function () {

			if (MGD.$lastCalled.context && MGD.$lastCalled.context.tagName && MGD.$lastCalled.context.tagName.search(/^(?:body|head|html)$/i) != -1) {
				MGDial.warning(MGLang.warnings.action_not_allowed);
				return false;
			}
			return true;
		},

		removeAttribute = function (ev) {

			ev.stopPropagation();

			var attr = JlQ(this).prevAll('.mg-property-input, .mg-changeable-input').first().attr('id').replace(/(mg-[^\-]+-)/, '');
			
			if (attr != 'attr-value') {
				MGD.addTransform("removeAttr('"+attr+"')", 'remove-attr');
			}
			JlQ(this).parent().remove();
		};


	that.extProperties = {};
	that.extAttributes = {};
	that.lastColorHasAlpha = false;

	
	that.getIsCSS = function () {return isCSS};

	that.reduceProp = function (p, res) {

		if (MGDefs.dimensionedProps[p]) {
			if (res[1] == res[3]) {
				if (res[0] == res[2]) {
					if (res[0] == res[1]) {
						res = [res[0]];
					}
					else {
						res = [res[0], res[1]];
					}
				}
				else {
					res.pop();
				}
			}
		}
		return res;
	};

	that.setEmptyTypespec = function () {

		JlQ('#mg-elprop-typespec').html('<div class="mg-empty-properties">No properties</div>');
	};

	that.activateSpinner = function (par) {

		if (!par || !par.jquery) {
			par = JlQ('.mg-spinner:visible', this);
		}
		par.each(function () {
			
			var $this = JlQ(this);

			if ($this.next('.JLui-spinner').length) return true;
			if (JlQ.browser.opera) adaptInput2Opera($this);
			else if (JlQ.browser.msie && !$this.val()) $this.val("0");

			$this.spinner().keyup(trySaveSpinner).next().find('span').mouseup(trySaveSpinner);

		});

	};

	that.activateBoxModel = function () {

		if (quickCallbacks.margintop) return;

		var res = '<div id="mg-border-style-current"><div mgtitle="none" class="mg-border-style-empty mg-qp-border-choices" style="border-style: solid; border-color:#F0E9E8;"><div class="mg-choice-label">none</div></div></div>';

		JlQ.each(['margin', 'border', 'padding'], function (i, kind) {
			
			JlQ.each(directions, function (j, dir) {
				
				var a = [kind, dir],
					prop, propName;

				if (kind == 'border') a.push('width');
				prop = a.join('');
				propName = a.join('-');

				quickCallbacks[prop] = {

					straight : function () {
						
						var value = String(JlQ('#mg-qp-' + propName).val()),
							constrain = JlQ('#mg-qp-constrain-' + kind).attr('checked'),
							pn = constrain ? propName.replace( '-' + dir, '') : propName;

						registerProp(pn, value + 'px');

						if (constrain) {
							JlQ.each(directions, function () {
								if (this == dir) return true;
								var $el = JlQ('#mg-qp-' + propName.replace(dir, this));
								$el.val(value);
								updateSpinnerSize($el.get(0));
							});
						}
					},
					
					reverse : function (value) {

						value = parseInt(value);
						JlQ('#mg-qp-' + propName).val(isNaN(value) ? '' : value);
						if (updatingProp || updatedDirs[kind]++ == 3) {
							updateBoxConstrain(kind);
						}
					},

					defStatus : 'inherit'
				};
			});
		});
		JlQ.each(MGDefs.autoProps['border-style'], function () {
			var val, label;
			if (this == 'none' || this == 'hidden') {
				val = 'solid;border-color:#F0E9E8;" class="mg-border-style-empty';
				label = '<div class="mg-choice-label">' + this + '</div>';
			}
			else {
				val = this + ';" class="';
				label = '';
			}
			res += '<div style="border-style:' + val + ' mg-qp-border-choices"  mgtitle="' + this + '">' + label + '</div>';
		});
		JlQ('#mg-qp-border-style').html(res)
			.find('div.mg-qp-border-choices').click(eventQuickProp);
		
		if (MGD.elIsSelected) {
			updateQuickProps();
		}
	};

	that.populateGroup = function (group, properties) {

		if (group == 'typespec') {
			that.setEmptyTypespec();
			return;
		}
		popGroup(group, properties);
	};

	that.fixProperties = function () {

		var specProps;

		if (MGD.lastCalled && MGD.lastCalled.tagName && typeSpecMap[MGD.lastCalled.tagName]) {
			specProps = MGDefs.properties.typespec[typeSpecMap[MGD.lastCalled.tagName]];
			JlQ('#mg-elprop-typespec').empty();
			popGroup('typespec', specProps);
			JlQ.each(specProps, function (i, v) {
				if (v) that.extProperties[v] = MGD.$lastCalled.css(v);
			});
		}
		else {
			that.setEmptyTypespec();
		}
		if (MGD.$lastCalled) {
			MGP.characterizeElement(MGD.$lastCalled, false, 'force');
			JlQ('#mg-edit-elem').toggleClass('mg-hidden', !!JlQ.autoCloseTags[MGD.lastCalled.tagName.toLowerCase()]);
		}
		JlQ('#mg-delete-elem').toggleClass('mg-hidden', that.currentMode == 'Add');

		fixProps(specProps);

		that.enableQuickProps();
	};

	that.toggleAttrButtons = function (ev) {

		if (ev.type == 'mouseover')	{

			var $this = JlQ(this).closest('.mg-removable-attr'),
				hasInput = $this.find('input').length;

			if ($this.find(MGP.currentMode == 'Add' ? '#mg-elattr-src' : '#mg-elattr-type, #mg-elattr-m9t, #mg-elattr-src').length) return;

			if (!hasInput && !JlQ('#mg-remove-attr').length) {
				$this.append('<div id="mg-remove-attr" class="mg-images mg-images-dark mg-images-overlay JLui-icon-circle-minus"></div>');
			}
			if (hasInput) {
				if (JlQ('.JLui-icon-bckg').length) {
					JlQ('.JLui-icon-bckg').show();
				}
				else {
					addEditIcons($this.get(0));
				}
			}
		}
		else {
			JlQ('#mg-remove-attr').remove();
			
			JlQ('.JLui-icon-bckg').hide();
		}
	};

	that.togglePropButtons = function (ev) {

		if (ev.type == 'mouseover')	{

			var $this = JlQ(this).closest('.mg-changeable-prop');

			if ($this.find('input').length) {
				JlQ('.JLui-icon-bckg').show();
			}
		}
		else {
			JlQ('.JLui-icon-bckg').hide();
		}
	};

	that.syncPositionProp = function (sel, value) {
		
		JlQ(sel).toggleClass('mg-quick-absolute', JlQ.inArray(value, MGMV.abPosEquiv) != -1);
	};

	that.editProperty = function (ev) {

		if (ev.isPropagationStopped()) return;

		var $par = JlQ(this),
			$el = $par.children('.mg-changeable-input'),
			isAdd = $par.hasClass('mg-add-rule'),
			id = $el.attr('id'),
			ic = $el.is('font') || isAdd,
			finalWidth, $entry, m;

		if (!$el.length || MGP.currentMode == 'Edit' && !ic && !MGD.elIsSelected || MGP.currentMode == 'Add' && !JlQ('.mg-newel-cont.mg-button-down').length) return;

		if (id == 'mg-elattr-m9t' || id == 'mg-elattr-type' && MGP.currentMode != 'Add') {
			MGDial.warning(MGLang.warnings.change_attr_denied);			
			return;
		}

		JlQ('.mg-added-attr, .mg-baloon').remove();
		
		if (JlQ('.mg-property-input').length && !isAdd) {
			cancelProperty();
		}
		isCSS = ic;

		if (!isAdd) {
			MGCR.cancelRule();
		}
		$el.replaceWith('<input type="text" class="mg-input mg-property-input" value=\'' + MGUtils.text2SQString($par.data('rval')) + '\' id="'+id+'" />');

		quickPropClicked = null;

		if (id.match(/color$/)) {
			editColor();
		}
		else if (m = id.match(imagePropRx)) {			
			editFile();
/*			if (m[1] == 'background-image') {
				initAutocomplete(id);
			}
*/
		}
//		else {
			initAutocomplete(id);
//		}
		finalWidth = $par.width() - $par.children('span, .#mg-add-rule-name').width() -3;
		$entry = JlQ('.mg-property-input');

		if (isCSS) {
			finalWidth -= 5;
		}
		if (isAdd) {
			finalWidth -= 5;
		}
		if ($par.children('.mg-prop-trigger').length) {
			finalWidth -= 12;
		}
		if (JlQ.browser.mozilla || JlQ.browser.opera) {
			finalWidth -= Math.floor(parseInt($par.css('padding-left')) / 3);
		}
		if (JlQ.browser.msie) {
			finalWidth -= 4;
		}
		if (finalWidth < 20) {
			$entry.css('width', '100%');
		}
		else {
			$entry.width(finalWidth);
		}
		if (isAdd) return;

		$entry.keydown(function(event) {

			switch (event.keyCode) {
				case 13:
					saveProperty();
					break;
				case 27:
					cancelProperty();
					break;
			}
		});

		setTimeout('MGED.addEditIcons(JlQ(".mg-property-input").parent().get(0))', 0);

		$entry.focus();
	};

	that.openEditarea = function (mode, value, options) {

		options = options || {};

		var isIE9 = JlQ.browser.msie && document.documentMode >= 9,
			wordWrap = !isIE9 && !options.no_wrap, 
			font = isIE9 ? '' : 'select_font,';
			ww = wordWrap ? 'word_wrap, ' : ''
			save = options.no_save ? '' : 'save, |, '
			charMap = '';
		
		if (!JlQ('.mg-panel-editarea').hasClass('mg-hidden')) {
			that.closeEditarea();
		}
		MGD.eaopen = mode;

		JlQ('.mg-panel-editarea').removeClass('mg-hidden');
		JlQ('#mg-editarea').val(value);

		if (options.no_wrap && JlQ.browser.webkit) {
			if (!options.EA_load_callback) options.EA_load_callback = '';
			options.EA_load_callback = "setTimeout(\"" + options.EA_load_callback.replace(/\"/g, '\\"') + "JlQ('#textarea', JlQ('#frame_mg-editarea').contents().get(0)).attr('wrap', 'off').cssImportant({'white-space': 'pre', 'word-wrap' : 'normal'});\", 1);";
		}

		editAreaLoader.init(JlQ.extend({
				id : 'mg-editarea',
				syntax: 'html',
				start_highlight: true,
				font_size: JlQ.browser.mozilla3 || JlQ.browser.opera ? 8 : (isIE9 ? 10 : 9),
				allow_resize: 'no',
				allow_toggle: false,
				toolbar: save + 'search, go_to_line, |, undo, redo, |, ' + font + '|,syntax_selection,|, ' + charMap + 'change_smooth_selection, highlight, reset_highlight, ' + ww + '|, help',
				syntax_selection_allow: 'css,html,js,php',
				language: 'en',
				word_wrap: wordWrap,
				show_line_colors: true,
				plugins: 'charmap'
			}, 
			options
		));

		MGP.bringToFront(JlQ('.mg-panel-editarea'));
	};

	that.closeEditarea = function () {

		if (!MGD.eaopen) return;

		MGD.eaopen = null;

		editAreaLoader.delete_instance('mg-editarea');
		JlQ('.mg-panel-editarea').addClass('mg-hidden');
		if (JlQ('.mg-panel-editarea').attr('style').search(/width\s*:/) != -1) {
			JlQ('#mg-editarea-container').css('padding-bottom', '4px');
		}
	};

	that.restoreText = function (id, value) {

		if (typeof(value) != 'undefined') {
			MGD.addTransform("html('"+MGUtils.text2SQString(value)+"')", 'change-html');
		}
		var html = MGD.$lastCalled.length ? MGD.$lastCalled.html() : '';

		//JlQ('#mg-save-text').remove();
		//JlQ('#mg-cancel-text').remove();
		JlQ('#mg-current-text').text(MGUtils.cutText(html, 40))
			.parent().addClass('mg-subpanel-text');

		MGED.closeEditarea();

		MGTut.nextStep('advancedEdit');
	},

	that.enableQuickProps = function () {

		updateQuickProps();

		JlQ('.mg-elprop-cover').hide();
	};

	that.disableQuickProps = function () {

		defaultQuickProps();

		JlQ('.mg-elprop-cover').show();
	};

	that.deleteElement = function () {

		if (!checkAllowedAction()) return;

		MGD.addTransform("remove()", 'remove-elem');

		if (MGD.elIsSelected) {
			MGP.toggleElementSelection();
			if (!JlQ.browser.opera) {
				JlQ('#mg-cursor').mousemove();
			}
			JlQ('#mg-cursor-temp').addClass('mg-hidden');
		}
	};

	that.init = function () {

		$shadowPanel = JlQ('.mg-panel-shadow');
		$shadowBase = JlQ('#mg-shadow-base');
		$shadowTarget = JlQ('#mg-shadow-target');

		JlQ('.JLui-icon-circle-triangle-s, .JLui-icon-circle-triangle-n').click(toggleGroupProperties);
		JlQ('#mg-add-attr').click(addAttributeEntry);
		JlQ('#mg-edit-elem').click(editElementText);
		JlQ('#mg-delete-elem').click(MGED.deleteElement);
		JlQ('#mg-editarea-cancel').click(MGED.closeEditarea);

		JlQ('#mg-prop-container').sortable({handle: '.mg-subpanel-head'});

		quickPanelInit();
	};

	that.getColorProperties = getColorProperties;
	that.editColorCancel = editColorCancel;
	that.openAutocomplete = openAutocomplete;
	that.clickAutocomplete = clickAutocomplete;
	that.closeAutocomplete = closeAutocomplete;
	that.removeAttribute = removeAttribute;
	that.addEditIcons = addEditIcons;
	that.changeElementProperty = changeElementProperty;
	that.cancelProperty = cancelProperty;
	that.cancelShadow = cancelShadow;
	that.fixProps = fixProps;
	that.toggleAddQuickPosition = toggleAddQuickPosition;
	that.togglePropView = togglePropView;
	that.updateQuickProps = updateQuickProps;
	that.eventQuickProp = eventQuickProp;
};